package com.aigc.sclassroom.ws;


import cn.hutool.json.JSONUtil;
import com.aigc.sclassroom.config.SpringConfigurator;
import com.aigc.sclassroom.pojo.SysUser;
import com.aigc.sclassroom.service.UserService;
import com.aigc.sclassroom.utils.JwtUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import jakarta.websocket.*;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Component

@ServerEndpoint(value = "/chatroom/{username}", configurator = SpringConfigurator.class)
public class ChatEndpoint {

    //记录日志
    private static final Logger log = LoggerFactory.getLogger(ChatEndpoint.class);
    //存储所有用户的用户名与session
    private static Map<String, Session> onlineUsers = new ConcurrentHashMap<>();


    @Autowired
    private UserService userService;


    @OnOpen
    public void onOpen(Session session, @PathParam("username") String userName) {
        try {
            onlineUsers.put(userName, session);
            log.info("有新用户加入，username={}, 当前在线人数为：{}", userName, onlineUsers.size());
            sendOnlineUsersToAllClients();
        } catch (Exception e) {
            try {
                session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Error opening session"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }


    @OnMessage
    public void onMessage(String message, Session session, @PathParam("username") String username) {
        log.info("服务端收到用户username={}的消息:{}", username, message);
        JSONObject obj = JSONUtil.parseObj(message);
        String toUsername = obj.getStr("to"); // to表示发送给哪个用户，比如 admin
        String text = obj.getStr("text"); // 发送的消息文本  hello
        // {"to": "admin", "text": "聊天文本"}
        Session toSession = onlineUsers.get(toUsername); // 根据 to用户名来获取 session，再通过session发送消息文本
        if (toSession != null) {
            // 服务器端 再把消息组装一下，组装后的消息包含发送人和发送的文本内容
            // {"from": "zhang", "text": "hello"}
            JSONObject jsonObject = new JSONObject();
            jsonObject.set("from", username);  // from 是 zhang
            jsonObject.set("text", text);  // text 同上面的text
            this.sendMessage(jsonObject.toString(), toSession);
            log.info("发送给用户username={}，消息：{}", toUsername, jsonObject.toString());
        } else {
            log.info("发送失败，未找到用户username={}的session", toUsername);
        }
    }



    @OnClose
    public void onClose(Session session) {
        String userName = findUserNameBySession(session);
        if (userName != null) {
            onlineUsers.remove(userName);
            SysUser sysUser = userService.findByUserName(userName);
            if (sysUser != null) {
                String leaveMessage = sysUser.getUserName() + " 离开了聊天室";
                sendAllMessage(leaveMessage);
            }
        }
    }


    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }


    /**
     * 服务端发送消息给客户端
     */
    private void sendMessage(String message, Session toSession) {
        try {
            log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
            toSession.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.error("服务端发送消息给客户端失败", e);
        }
    }




    private void sendOnlineUsersToAllClients() {
        JSONObject result = new JSONObject();
        JSONArray array = new JSONArray();
        for (String username : onlineUsers.keySet()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("username", username);
            array.add(jsonObject);
        }
        result.put("users", array);
        sendAllMessage(result.toString());
    }


    /**
     * 服务端发送消息给所有客户端
     * @param message
     * @return
     */




    private void sendAllMessage(String message) {
        for (Session session : onlineUsers.values()) {
            log.info("服务端给客户端[{}]发送消息{}",session.getId(),message);
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                log.error("服务端发送消息给客户端失败",e);
            }
        }
    }

    private String findUserNameBySession(Session session) {
        for (Map.Entry<String, Session> entry : onlineUsers.entrySet()) {
            if (entry.getValue().equals(session)) {
                return entry.getKey();
            }
        }
        return null;
    }
}
